Skip to content

feat: MySQL/MariaDB adapter - #34

Merged
ihistand merged 12 commits into
mainfrom
feat/mysql-adapter
Jun 17, 2026
Merged

feat: MySQL/MariaDB adapter#34
ihistand merged 12 commits into
mainfrom
feat/mysql-adapter

Conversation

@ihistand

Copy link
Copy Markdown
Collaborator

Implements a single mysql warehouse adapter per planning/specs/2026-06-17-mysql-mariadb-adapter-design.md. One adapter generates portable MySQL-dialect SQL that runs against both MySQL and MariaDB — engine-specific features ride through operations, mirroring how the BigQuery/Postgres adapters lean on the engine for the heavy lifting.

What's included

  • ProtoMysqlConnection added to the WarehouseConfig union (protos/configs.proto).
  • Coremysql accepted in supportedWarehouses; MySQL backtick quoting in CompilationSql (two-part `schema`.`name`, backtick-quoted assertion columns, backslash string escaping).
  • Adapter triad (mirrors Postgres):
  • CLI — credentials validation, init scaffolds a mysql .df-credentials.json, --warehouse mysql accepted, adapter wired into run/test.
  • Tests — unit coverage for quoting + DDL/DML generation; an integration spec that PASSES against both mysql:8 (3306) and mariadb:11 (3307) (full project run, incremental append + upsert idempotency, assertion pass/fail, EXPLAIN evaluate, fail-fast bad creds). Fixtures + tools/mysql/run-mysql-db.sh.

Verification

  • ./scripts/docker-bazel test //core/... //cli/... — all pass except the pre-existing, credentials-gated //cli:index_run_e2e_test (fails identically on main; unrelated to this change).
  • Integration spec green on both engines.
  • CLI smoke: init --warehouse mysql scaffolds correctly. (Full CLI compile/run end-to-end needs the 1.5.0 core on npm — the standalone compile installs @sqlanvil/core@<version>; the in-repo build is fully verified via the integration suite, which uses the local core tarball.)

Deferred (follow-up PRs)

Materialized views (error only), a mysql: {} options block (engine/indexes/partitioning), description/columnsCOMMENT metadata, and introspect for MySQL sources.

Version bump to 1.5.0 + publish is a separate release step after merge.

🤖 Generated with Claude Code

ihistand and others added 12 commits June 17, 2026 08:26
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- supportedWarehouses now includes mysql; main_test rejection case uses snowflake
- CompilationSql resolveTarget emits `schema`.`name` for mysql (no catalog level)
- indexAssertion backtick-quotes columns; sqlString uses backslash escaping for mysql
- unit tests for resolveTarget/sqlString/indexAssertion mysql branches

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Table CTAS, CREATE OR REPLACE VIEW, incremental (CTAS + unique index then
ON DUPLICATE KEY UPDATE upsert), assertion via view + row count. Materialized
views error out (deferred). Wired into the ExecutionSql dispatcher.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mysql2-backed pool with withClientLock + single release path, verifyConnection
fail-fast, and a convertFieldType mapping MySQL DATA_TYPEs to field primitives.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
create() with fail-fast verify + optional TLS, withClientLock delegating to the
pool executor, EXPLAIN-based evaluate, information_schema introspection
(tables/table/search/schemas), CREATE DATABASE IF NOT EXISTS, deleteTable.
setMetadata is a deferred no-op for the MVP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- credentials.read() validates MysqlConnection (host required)
- init scaffolds a mysql .df-credentials.json template
- warehouseOption accepts mysql; run/test commands create MySqlDbAdapter

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MysqlFixture (2-arg ctor, env-bypass for the docker-bazel path; same class
serves MySQL 3306 and MariaDB 3307) + run-mysql-db.sh launcher + BUILD.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Full-project run (table/view/incremental/merge/assertions), incremental append +
upsert idempotency, EXPLAIN-based evaluate, fail-fast bad creds — verified
PASSED on both mysql:8 (3306) and mariadb:11 (3307). Adds MYSQL_* env
forwarding to scripts/docker-bazel; upsertInto only emits ON DUPLICATE KEY
UPDATE when a uniqueKey exists (plain append otherwise).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds mysql2 to the cli package.json deps and mysql2/promise to the rollup
externals (rollup matches the import specifier exactly), so the adapter's
mysql2/promise import is not bundled. Fixes the cli bundle build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nt comments

- convertFieldType maps BIT->INTEGER, JSON/TIME->STRING; documents binary/blob/
  geometry falling through to UNKNOWN (introspection-only metadata)
- comment the upsertInto no-metadata fallback invariant and the byteLimit/
  client-side rowLimit divergence from the streaming Postgres path

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant